package ru.ifmo.trafficspy.analyzer;

import java.io.PrintWriter;
import java.util.List;
import java.util.Scanner;

import ru.ifmo.trafficspy.analyzer.clustering.KMeansClusterizer;
import ru.ifmo.trafficspy.analyzer.hmm.HiddenMarkovModel;
import ru.ifmo.trafficspy.common.Item;

public class TrafficModel {
	private HiddenMarkovModel hmm;
	public KMeansClusterizer packetClusterizer;
	private KMeansClusterizer intervalClusterizer;
	private final String description;
	
	public TrafficModel(HiddenMarkovModel hmm, KMeansClusterizer packetClusterizer,
			KMeansClusterizer intervalClusterizer, String description) {
		this.description = description;
		this.hmm = hmm;
		this.packetClusterizer = packetClusterizer;
		this.intervalClusterizer = intervalClusterizer;
	}
	
	public void write(PrintWriter out) {
		out.println(description);
		hmm.write(out);
		packetClusterizer.write(out);
		intervalClusterizer.write(out);
	}
	
	public static TrafficModel read(Scanner in) {
		String description = in.nextLine();
		HiddenMarkovModel hmm = HiddenMarkovModel.read(in);
		KMeansClusterizer packetClusterizer = KMeansClusterizer.read(in);
		KMeansClusterizer intervalClusterizer = KMeansClusterizer.read(in);
		return new TrafficModel(hmm, packetClusterizer, intervalClusterizer, description);
	}
	
	public double getProbability(List<Item> traffic) {
		int n = packetClusterizer.getClusterCount();
		int[] clusters = new int[traffic.size()];
		{
			int i = 0;
			for (Item item : traffic) {
				if (i % 2 == 0) {
					clusters[i] = packetClusterizer.getCluster(item.getValue());
				} else {
					clusters[i] = n + intervalClusterizer.getCluster(item.getValue());
				}
				i++;
			}
		}
		for (int x : clusters) {
			if (x == -1) {
				return 0;
			}
		}
		return hmm.probabilityOfSequence(clusters);
	}

	public String getDescription() {
		return description;
	}
	
}
